package com.group.voting_system.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.group.voting_system.entity.Candidate;
import com.group.voting_system.entity.User;
import com.group.voting_system.entity.Vote;
import com.group.voting_system.exception.ParamNotValidException;
import com.group.voting_system.exception.RecordNotExistException;
import com.group.voting_system.service.ICandidateService;
import com.group.voting_system.service.IUserService;
import com.group.voting_system.service.IVoteService;
import com.group.voting_system.utils.RestResult;
import com.group.voting_system.utils.ResultUtil;
import com.group.voting_system.utils.SecureUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * <p>
 *  逻辑控制器
 *  用户的投票操作都写在这里
 * </p>
 *
 * @author xyf
 * @since 2019-04-15
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    IUserService userService;

    @Autowired
    ICandidateService candidateService;

    @Autowired
    IVoteService voteService;

    @Value("${assistant}")
    Integer a;

    @Value("${teacher}")
    Integer t;
//跳转到user/list
    @GetMapping("/list")
    public String list(){
        return "user/list";
    }
//跳转到user/add
    @GetMapping("/add")
    public String add(){
        return "user/add";
    }

    //user/add点击修改跳转页面
    @GetMapping("/edit")
    public String edit(){
        return "user/edit";
    }

    @GetMapping("")
    @ResponseBody
    public RestResult getAll(@RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
                             @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize){
        IPage<User> page = userService.selectAllUsers(new Page<User>(pageNo, pageSize).setDesc("id"));
        return ResultUtil.success("请求成功", page);
    }

    /**
     * 查询所有不属于当前投票事件的用户
     * @param pageNo
     * @param pageSize
     * @param vid 投票事件id
     * @return
     */
    @ResponseBody
    @GetMapping("/{vid}")
    public RestResult list(@RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
                           @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
                           @PathVariable("vid") Integer vid){
        IPage<User> page = userService.pageUserNotCandidate(new Page<>(pageNo, pageSize), vid, null);
        return ResultUtil.success("", page);
    }

    @PostMapping("")
    @ResponseBody
    public RestResult insert(@RequestBody User user){

        //默认密码为工号
        user.setPassword(SecureUtil.encryptBasedDes(user.getJobNumber()));
        boolean save = userService.save(user);
        if (!save)
            return ResultUtil.fail("添加失败");
        return ResultUtil.success("添加成功");
    }

    @PutMapping("")
    @ResponseBody
    public RestResult revise(@RequestBody User user){
        boolean b = userService.updateById(user);
        if (!b)
            return ResultUtil.fail("更新失败");
        return ResultUtil.success("更新成功");
    }

    @DeleteMapping("/{id}")
    @ResponseBody
    public RestResult del(@PathVariable("id") Integer id){

        boolean b = userService.removeById(id);
        if (!b)
            return ResultUtil.fail("删除失败");
        return ResultUtil.success("删除成功");
    }

    /**
     * 搜索符合条件的
     * 不是该投票事件候选人的用户
     * @param vid
     * @return
     */
    @ResponseBody
    @GetMapping("/search/{vid}")
    public RestResult searchByVid(@RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
                                  @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
                                  @RequestParam(value = "jobNumber", required = false) String jobNumber,
                                  @RequestParam(value = "username", required = false) String username,
                                  @RequestParam(value = "academy", required = false) String academy,
                                  @RequestParam(value = "sex", required = false) Boolean sex,
                                  @PathVariable("vid") Integer vid){
        User condition = new User();
        condition.setUsername(username)
                .setAcademy(academy)
                .setJobNumber(jobNumber)
                .setSex(sex);
        IPage<User> page = userService.pageUserNotCandidate(new Page<>(pageNo, pageSize), vid, condition);
        return ResultUtil.success("", page);
    }

    //进入投票页面
    @GetMapping("/vote/{vid}")
    public String votePage(@PathVariable("vid")Integer vid, Model model){
        List<Candidate> candidates = candidateService.getCandidateByVId(vid);
        Vote vote = voteService.getById(vid);
        Integer leftDays = voteService.getLeftDays(vid);
        model.addAttribute("candidates", candidates);
        //实现投票分类，算法时间复杂度较高
        //先遍历整个数组，判断到底有多少种职位
        Set<String> rankSet = new HashSet<>();
        candidates.forEach(x -> {
            rankSet.add(x.getRank());
        });
        model.addAttribute("ranks", rankSet);
        model.addAttribute("vote", vote);
        model.addAttribute("leftDays", leftDays < 0 ? 0 : leftDays);
        return "vote/new_index";
    }

    //用户投票
    @ResponseBody
    @PostMapping("/vote2candidate")
    public RestResult vote(@RequestParam("vid") Integer vid,
                           @RequestBody Map<String, Object> map,
                           HttpServletRequest request,
                           HttpSession session
                           ) throws ParamNotValidException, RecordNotExistException {

        List<String> c = (List<String>) map.get("c");
        Set<Integer> c1 = new HashSet<>();
        String jobNumber = (String) map.get("jobNumber");
        String password = (String) map.get("password");
        //获取验证码
        String code1 = (String) map.get("code");
        String code = (String) session.getAttribute("code");
        request.getSession().removeAttribute("code");

        if (code == null)
            return ResultUtil.fail(102, "验证码过期");

        //验证码验证
        if (!code1.toLowerCase().equals(code.toLowerCase())){
            return ResultUtil.fail(101,"验证码错误");
        }

        c.forEach(x-> c1.add(Integer.parseInt(x)));

        //先登录
        User user = userService.getUserByJobNumAndPass(new User().setJobNumber(jobNumber).setPassword(password));
        if (user == null)
            throw new RecordNotExistException("用户名或密码错误");
        //开始投票
        if (c1.size() != (a + t))
            throw new ParamNotValidException("辅导员要投" + a + "票，教师要投" + t + "票");

        boolean b = userService.userVote(vid, user.getId(), c1, request.getRemoteAddr());

        return b ? ResultUtil.success("投票成功！") : ResultUtil.fail(500 , "投票失败！");
    }
}
